package com.zp.mall.product.service.impl;

import com.zp.mall.product.dao.CategoryBrandRelationDao;
import com.zp.mall.product.entity.CategoryBrandRelationEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zp.common.utils.PageUtils;
import com.zp.common.utils.Query;

import com.zp.mall.product.dao.CategoryDao;
import com.zp.mall.product.entity.CategoryEntity;
import com.zp.mall.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Autowired
    private CategoryBrandRelationDao categoryBrandRelationDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listWithTree() {
        //1、获取所有数据
        List<CategoryEntity> categoryEntities = baseMapper.selectList (null);
        //2、组装成父子的树形结构
        List<CategoryEntity> collect = categoryEntities.stream ().filter (c -> {
            return c.getParentCid () == 0 && c.getShowStatus () == 1;  //顶级父类类别 且是在页面显示
        }).map (c -> {
            //获取子类类别
            //参数一：要封装子类类别的父类   参数二：所有数据
            List<CategoryEntity> categoryEntityList = getSonCategoryList (c, categoryEntities);
            c.setChildren (categoryEntityList);
            return c;
        }).sorted ((c1, c2)->{
            return (c1.getSort () == null ? 0 : c1.getSort ()) - (c2.getSort () == null ? 0 : c2.getSort ());
        }).collect (Collectors.toList ());
        return collect;
    }

    private List<CategoryEntity> getSonCategoryList(CategoryEntity categoryEntity, List<CategoryEntity> categoryEntities) {
        return categoryEntities.stream ().filter (c -> {
            //Long 对象用 == 比较可能地址不一样
            /*
            对于Integer Double Long对象对比都有个拆箱，值超出了缓存池如果直接用==比较就会有错
            缓存池范围[-128,127]
             */
            return c.getParentCid ().intValue () == categoryEntity.getCatId ().intValue () && c.getShowStatus () == 1;  //查找子类的parentId为当前要查找子类类别对象的id
        }).map (c -> {
            //继续递归 查询当前类别的子类  直到消费完流
            List<CategoryEntity> sonCategoryList = getSonCategoryList (c, categoryEntities);
            c.setChildren (sonCategoryList);
            return c;
        }).sorted ((c1, c2)->{
            return (c1.getSort () == null ? 0 : c1.getSort ()) - (c2.getSort () == null ? 0 : c2.getSort ());
        }).collect (Collectors.toList ());
    }

    @Override
    public void removeMenuByIds(List<Long> catIds) {
        //TODO 检查当前删除的菜单是否被其他地方引用

        //使用Mybatis-plus逻辑删除
        baseMapper.deleteBatchIds (catIds);
    }

    // [2,25,225]
    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> list = new ArrayList<> ();
        findParentPath(catelogId, list);
        Collections.reverse (list); //反转list
        return list.toArray (new Long[list.size ()]);
    }

    private void findParentPath(Long catelogId, List<Long> list) {
        list.add (catelogId);
        CategoryEntity byId = this.getById (catelogId);
        if (byId.getParentCid () != 0){
            findParentPath (byId.getParentCid (), list);
        }
    }

    /**
     * 修改分类信息
     * 如果分类名称修改了
     * 修改其它表存的与之对应的分类名称
     * @param category
     */
    @Override
    @Transactional
    public void updateCategory(CategoryEntity category) {
        CategoryEntity byId = this.getById (category.getCatId ());
        //修改分类表
        this.updateById (category);
        //判断分类名称是否被修改
        if (!byId.getName ().equals (category.getName ())){
            //分类名称被修改
            //修改 品牌-分类中间表的分类名称
            categoryBrandRelationDao.updateCategoryNameByCatId(category.getCatId (), category.getName ());

            //TODO 修改其它存了分类名称的表
        }
    }
}